
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
  <head>
    <meta charset="utf-8" />
    <title>functools --- 高阶函数和可调用对象上的操作 &#8212; Python 3.7.8 文档</title>
    <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    
    <script type="text/javascript" src="../_static/sidebar.js"></script>
    
    <link rel="search" type="application/opensearchdescription+xml"
          title="在 Python 3.7.8 文档 中搜索"
          href="../_static/opensearch.xml"/>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="copyright" title="版权所有" href="../copyright.html" />
    <link rel="next" title="operator --- 标准运算符替代函数" href="operator.html" />
    <link rel="prev" title="itertools --- 为高效循环而创建迭代器的函数" href="itertools.html" />
    <link rel="shortcut icon" type="image/png" href="../_static/py.png" />
    <link rel="canonical" href="https://docs.python.org/3/library/functools.html" />
    
    <script type="text/javascript" src="../_static/copybutton.js"></script>
    
    
    
    
    <style>
      @media only screen {
        table.full-width-table {
            width: 100%;
        }
      }
    </style>
 

  </head><body>
  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="operator.html" title="operator --- 标准运算符替代函数"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="itertools.html" title="itertools --- 为高效循环而创建迭代器的函数"
             accesskey="P">上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="functional.html" accesskey="U">函数式编程模块</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>    

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="module-functools">
<span id="functools-higher-order-functions-and-operations-on-callable-objects"></span><h1><a class="reference internal" href="#module-functools" title="functools: Higher-order functions and operations on callable objects."><code class="xref py py-mod docutils literal notranslate"><span class="pre">functools</span></code></a> --- 高阶函数和可调用对象上的操作<a class="headerlink" href="#module-functools" title="永久链接至标题">¶</a></h1>
<p><strong>源代码:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.7/Lib/functools.py">Lib/functools.py</a></p>
<hr class="docutils" />
<p><a class="reference internal" href="#module-functools" title="functools: Higher-order functions and operations on callable objects."><code class="xref py py-mod docutils literal notranslate"><span class="pre">functools</span></code></a> 模块应用于高阶函数，即——参数或（和）返回值为其他函数的函数。通常来说，此模块的功能适用于所有可调用对象。</p>
<p><a class="reference internal" href="#module-functools" title="functools: Higher-order functions and operations on callable objects."><code class="xref py py-mod docutils literal notranslate"><span class="pre">functools</span></code></a> 模块定义了以下函数:</p>
<dl class="function">
<dt id="functools.cmp_to_key">
<code class="sig-prename descclassname">functools.</code><code class="sig-name descname">cmp_to_key</code><span class="sig-paren">(</span><em class="sig-param">func</em><span class="sig-paren">)</span><a class="headerlink" href="#functools.cmp_to_key" title="永久链接至目标">¶</a></dt>
<dd><p>将(旧式的)比较函数转换为新式的 <a class="reference internal" href="../glossary.html#term-key-function"><span class="xref std std-term">key function</span></a> .  在类似于 <a class="reference internal" href="functions.html#sorted" title="sorted"><code class="xref py py-func docutils literal notranslate"><span class="pre">sorted()</span></code></a> ， <a class="reference internal" href="functions.html#min" title="min"><code class="xref py py-func docutils literal notranslate"><span class="pre">min()</span></code></a> ， <a class="reference internal" href="functions.html#max" title="max"><code class="xref py py-func docutils literal notranslate"><span class="pre">max()</span></code></a> ， <a class="reference internal" href="heapq.html#heapq.nlargest" title="heapq.nlargest"><code class="xref py py-func docutils literal notranslate"><span class="pre">heapq.nlargest()</span></code></a> ， <a class="reference internal" href="heapq.html#heapq.nsmallest" title="heapq.nsmallest"><code class="xref py py-func docutils literal notranslate"><span class="pre">heapq.nsmallest()</span></code></a> ， <a class="reference internal" href="itertools.html#itertools.groupby" title="itertools.groupby"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.groupby()</span></code></a> 等函数的 <cite>key</cite> 参数中使用。此函数主要用作将 Python 2 程序转换至新版的转换工具，以保持对比较函数的兼容。</p>
<p>比较函数意为一个可调用对象，该对象接受两个参数并比较它们，结果为小于则返回一个负数，相等则返回零，大于则返回一个正数。key function则是一个接受一个参数，并返回另一个用以排序的值的可调用对象。</p>
<p>示例:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nb">sorted</span><span class="p">(</span><span class="n">iterable</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">cmp_to_key</span><span class="p">(</span><span class="n">locale</span><span class="o">.</span><span class="n">strcoll</span><span class="p">))</span>  <span class="c1"># locale-aware sort order</span>
</pre></div>
</div>
<p>有关排序示例和简要排序教程，请参阅 <a class="reference internal" href="../howto/sorting.html#sortinghowto"><span class="std std-ref">排序指南</span></a> 。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.2 新版功能.</span></p>
</div>
</dd></dl>

<dl class="function">
<dt id="functools.lru_cache">
<code class="sig-prename descclassname">&#64;</code><code class="sig-prename descclassname">functools.</code><code class="sig-name descname">lru_cache</code><span class="sig-paren">(</span><em class="sig-param">maxsize=128</em>, <em class="sig-param">typed=False</em><span class="sig-paren">)</span><a class="headerlink" href="#functools.lru_cache" title="永久链接至目标">¶</a></dt>
<dd><p>一个为函数提供缓存功能的装饰器，缓存 <em>maxsize</em> 组传入参数，在下次以相同参数调用时直接返回上一次的结果。用以节约高开销或I/O函数的调用时间。</p>
<p>由于使用了字典存储缓存，所以该函数的固定参数和关键字参数必须是可哈希的。</p>
<p>不同模式的参数可能被视为不同从而产生多个缓存项，例如, <cite>f(a=1, b=2)</cite> 和 <cite>f(b=2, a=1)</cite> 因其参数顺序不同，可能会被缓存两次。</p>
<p>如果 <em>maxsize</em> 设置为 <code class="docutils literal notranslate"><span class="pre">None</span></code> ，LRU功能将被禁用且缓存数量无上限。 <em>maxsize</em> 设置为2的幂时可获得最佳性能。</p>
<p>如果 <em>typed</em> 设置为true，不同类型的函数参数将被分别缓存。例如， <code class="docutils literal notranslate"><span class="pre">f(3)</span></code> 和 <code class="docutils literal notranslate"><span class="pre">f(3.0)</span></code> 将被视为不同而分别缓存。</p>
<p>为了衡量缓存的有效性以便调整 <em>maxsize</em> 形参，被装饰的函数带有一个 <code class="xref py py-func docutils literal notranslate"><span class="pre">cache_info()</span></code> 函数。当调用 <code class="xref py py-func docutils literal notranslate"><span class="pre">cache_info()</span></code> 函数时，返回一个具名元组，包含命中次数 <em>hits</em>，未命中次数 <em>misses</em> ，最大缓存数量 <em>maxsize</em> 和 当前缓存大小 <em>currsize</em>。在多线程环境中，命中数与未命中数是不完全准确的。</p>
<p>该装饰器也提供了一个用于清理/使缓存失效的函数 <code class="xref py py-func docutils literal notranslate"><span class="pre">cache_clear()</span></code> 。</p>
<p>原始的未经装饰的函数可以通过 <code class="xref py py-attr docutils literal notranslate"><span class="pre">__wrapped__</span></code> 属性访问。它可以用于检查、绕过缓存，或使用不同的缓存再次装饰原始函数。</p>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Cache_algorithms#Examples">“最久未使用算法”（LRU）缓存</a> 在“最近的调用是即将到来的调用的最佳预测因子”时性能最好（比如，新闻服务器上最受欢迎的文章倾向于每天更改）。 “缓存大小限制”参数保证缓存不会在长时间运行的进程比如说网站服务器上无限制的增加自身的大小。</p>
<p>一般来说，LRU缓存只在当你想要重用之前计算的结果时使用。因此，用它缓存具有副作用的函数、需要在每次调用时创建不同、易变的对象的函数或者诸如time（）或random（）之类的不纯函数是没有意义的。</p>
<p>静态 Web 内容的 LRU 缓存示例:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@lru_cache</span><span class="p">(</span><span class="n">maxsize</span><span class="o">=</span><span class="mi">32</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get_pep</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
    <span class="s1">&#39;Retrieve text of a Python Enhancement Proposal&#39;</span>
    <span class="n">resource</span> <span class="o">=</span> <span class="s1">&#39;http://www.python.org/dev/peps/pep-</span><span class="si">%04d</span><span class="s1">/&#39;</span> <span class="o">%</span> <span class="n">num</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">with</span> <span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">resource</span><span class="p">)</span> <span class="k">as</span> <span class="n">s</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">s</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
    <span class="k">except</span> <span class="n">urllib</span><span class="o">.</span><span class="n">error</span><span class="o">.</span><span class="n">HTTPError</span><span class="p">:</span>
        <span class="k">return</span> <span class="s1">&#39;Not Found&#39;</span>

<span class="o">&gt;&gt;&gt;</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">290</span><span class="p">,</span> <span class="mi">308</span><span class="p">,</span> <span class="mi">320</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">218</span><span class="p">,</span> <span class="mi">320</span><span class="p">,</span> <span class="mi">279</span><span class="p">,</span> <span class="mi">289</span><span class="p">,</span> <span class="mi">320</span><span class="p">,</span> <span class="mi">9991</span><span class="p">:</span>
<span class="o">...</span>     <span class="n">pep</span> <span class="o">=</span> <span class="n">get_pep</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="o">...</span>     <span class="nb">print</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">pep</span><span class="p">))</span>

<span class="o">&gt;&gt;&gt;</span> <span class="n">get_pep</span><span class="o">.</span><span class="n">cache_info</span><span class="p">()</span>
<span class="n">CacheInfo</span><span class="p">(</span><span class="n">hits</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">misses</span><span class="o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n">maxsize</span><span class="o">=</span><span class="mi">32</span><span class="p">,</span> <span class="n">currsize</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>
</pre></div>
</div>
<p>以下是使用缓存通过 <a class="reference external" href="https://zh.wikipedia.org/wiki/动态规划">动态规划</a>  计算 <a class="reference external" href="https://zh.wikipedia.org/wiki/斐波那契数列">斐波那契数列</a>  的例子。</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@lru_cache</span><span class="p">(</span><span class="n">maxsize</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">n</span>
    <span class="k">return</span> <span class="n">fib</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">fib</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>

<span class="o">&gt;&gt;&gt;</span> <span class="p">[</span><span class="n">fib</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">16</span><span class="p">)]</span>
<span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">21</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">55</span><span class="p">,</span> <span class="mi">89</span><span class="p">,</span> <span class="mi">144</span><span class="p">,</span> <span class="mi">233</span><span class="p">,</span> <span class="mi">377</span><span class="p">,</span> <span class="mi">610</span><span class="p">]</span>

<span class="o">&gt;&gt;&gt;</span> <span class="n">fib</span><span class="o">.</span><span class="n">cache_info</span><span class="p">()</span>
<span class="n">CacheInfo</span><span class="p">(</span><span class="n">hits</span><span class="o">=</span><span class="mi">28</span><span class="p">,</span> <span class="n">misses</span><span class="o">=</span><span class="mi">16</span><span class="p">,</span> <span class="n">maxsize</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">currsize</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span>
</pre></div>
</div>
<div class="versionadded">
<p><span class="versionmodified added">3.2 新版功能.</span></p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.3 版更改: </span>添加 <em>typed</em> 选项。</p>
</div>
</dd></dl>

<dl class="function">
<dt id="functools.total_ordering">
<code class="sig-prename descclassname">&#64;</code><code class="sig-prename descclassname">functools.</code><code class="sig-name descname">total_ordering</code><a class="headerlink" href="#functools.total_ordering" title="永久链接至目标">¶</a></dt>
<dd><p>给定一个声明一个或多个全比较排序方法的类，这个类装饰器实现剩余的方法。这减轻了指定所有可能的全比较操作的工作。</p>
<p>此类必须包含以下方法之一：<a class="reference internal" href="../reference/datamodel.html#object.__lt__" title="object.__lt__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__lt__()</span></code></a> 、<a class="reference internal" href="../reference/datamodel.html#object.__le__" title="object.__le__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__le__()</span></code></a>、<a class="reference internal" href="../reference/datamodel.html#object.__gt__" title="object.__gt__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__gt__()</span></code></a> 或 <a class="reference internal" href="../reference/datamodel.html#object.__ge__" title="object.__ge__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__ge__()</span></code></a>。另外，此类必须支持 <a class="reference internal" href="../reference/datamodel.html#object.__eq__" title="object.__eq__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__eq__()</span></code></a> 方法。</p>
<p>例如</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@total_ordering</span>
<span class="k">class</span> <span class="nc">Student</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">_is_valid_operand</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="p">(</span><span class="nb">hasattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="s2">&quot;lastname&quot;</span><span class="p">)</span> <span class="ow">and</span>
                <span class="nb">hasattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="s2">&quot;firstname&quot;</span><span class="p">))</span>
    <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_is_valid_operand</span><span class="p">(</span><span class="n">other</span><span class="p">):</span>
            <span class="k">return</span> <span class="bp">NotImplemented</span>
        <span class="k">return</span> <span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">lastname</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">firstname</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span> <span class="o">==</span>
                <span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">lastname</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="n">other</span><span class="o">.</span><span class="n">firstname</span><span class="o">.</span><span class="n">lower</span><span class="p">()))</span>
    <span class="k">def</span> <span class="fm">__lt__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_is_valid_operand</span><span class="p">(</span><span class="n">other</span><span class="p">):</span>
            <span class="k">return</span> <span class="bp">NotImplemented</span>
        <span class="k">return</span> <span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">lastname</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">firstname</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span> <span class="o">&lt;</span>
                <span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">lastname</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="n">other</span><span class="o">.</span><span class="n">firstname</span><span class="o">.</span><span class="n">lower</span><span class="p">()))</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>虽然此装饰器使得创建具有良好行为的完全有序类型变得非常容易，但它 <em>确实</em> 是以执行速度更缓慢和派生比较方法的堆栈回溯更复杂为代价的。 如果性能基准测试表明这是特定应用的瓶颈所在，则改为实现全部六个富比较方法应该会轻松提升速度。</p>
</div>
<div class="versionadded">
<p><span class="versionmodified added">3.2 新版功能.</span></p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.4 版更改: </span>现在已支持从未识别类型的下层比较函数返回 NotImplemented 异常。</p>
</div>
</dd></dl>

<dl class="function">
<dt id="functools.partial">
<code class="sig-prename descclassname">functools.</code><code class="sig-name descname">partial</code><span class="sig-paren">(</span><em class="sig-param">func</em>, <em class="sig-param">*args</em>, <em class="sig-param">**keywords</em><span class="sig-paren">)</span><a class="headerlink" href="#functools.partial" title="永久链接至目标">¶</a></dt>
<dd><p>返回一个新的 <a class="reference internal" href="#partial-objects"><span class="std std-ref">部分对象</span></a>，当被调用时其行为类似于 <em>func</em> 附带位置参数 <em>args</em> 和关键字参数 <em>keywords</em> 被调用。 如果为调用提供了更多的参数，它们会被附加到 <em>args</em>。 如果提供了额外的关键字参数，它们会扩展并重载 <em>keywords</em>。 大致等价于:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">partial</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">keywords</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">newfunc</span><span class="p">(</span><span class="o">*</span><span class="n">fargs</span><span class="p">,</span> <span class="o">**</span><span class="n">fkeywords</span><span class="p">):</span>
        <span class="n">newkeywords</span> <span class="o">=</span> <span class="n">keywords</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
        <span class="n">newkeywords</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">fkeywords</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">*</span><span class="n">fargs</span><span class="p">,</span> <span class="o">**</span><span class="n">newkeywords</span><span class="p">)</span>
    <span class="n">newfunc</span><span class="o">.</span><span class="n">func</span> <span class="o">=</span> <span class="n">func</span>
    <span class="n">newfunc</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span>
    <span class="n">newfunc</span><span class="o">.</span><span class="n">keywords</span> <span class="o">=</span> <span class="n">keywords</span>
    <span class="k">return</span> <span class="n">newfunc</span>
</pre></div>
</div>
<p><a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-func docutils literal notranslate"><span class="pre">partial()</span></code></a> 会被“冻结了”一部分函数参数和/或关键字的部分函数应用所使用，从而得到一个具有简化签名的新对象。 例如，<a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-func docutils literal notranslate"><span class="pre">partial()</span></code></a> 可用来创建一个行为类似于 <a class="reference internal" href="functions.html#int" title="int"><code class="xref py py-func docutils literal notranslate"><span class="pre">int()</span></code></a> 函数的可调用对象，其中 <em>base</em> 参数默认为二：</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">partial</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">basetwo</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">basetwo</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> <span class="s1">&#39;Convert base 2 string to an int.&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">basetwo</span><span class="p">(</span><span class="s1">&#39;10010&#39;</span><span class="p">)</span>
<span class="go">18</span>
</pre></div>
</div>
</dd></dl>

<dl class="class">
<dt id="functools.partialmethod">
<em class="property">class </em><code class="sig-prename descclassname">functools.</code><code class="sig-name descname">partialmethod</code><span class="sig-paren">(</span><em class="sig-param">func</em>, <em class="sig-param">*args</em>, <em class="sig-param">**keywords</em><span class="sig-paren">)</span><a class="headerlink" href="#functools.partialmethod" title="永久链接至目标">¶</a></dt>
<dd><p>返回一个新的 <a class="reference internal" href="#functools.partialmethod" title="functools.partialmethod"><code class="xref py py-class docutils literal notranslate"><span class="pre">partialmethod</span></code></a> 描述器，其行为类似 <a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-class docutils literal notranslate"><span class="pre">partial</span></code></a> 但它被设计用作方法定义而非直接用作可调用对象。</p>
<p><em>func</em> 必须是一个 <a class="reference internal" href="../glossary.html#term-descriptor"><span class="xref std std-term">descriptor</span></a> 或可调用对象（同属两者的对象例如普通函数会被当作描述器来处理）。</p>
<p>当 <em>func</em> 是一个描述器（例如普通 Python 函数, <a class="reference internal" href="functions.html#classmethod" title="classmethod"><code class="xref py py-func docutils literal notranslate"><span class="pre">classmethod()</span></code></a>, <a class="reference internal" href="functions.html#staticmethod" title="staticmethod"><code class="xref py py-func docutils literal notranslate"><span class="pre">staticmethod()</span></code></a>, <code class="xref py py-func docutils literal notranslate"><span class="pre">abstractmethod()</span></code> 或其他 <a class="reference internal" href="#functools.partialmethod" title="functools.partialmethod"><code class="xref py py-class docutils literal notranslate"><span class="pre">partialmethod</span></code></a> 的实例）时, 对 <code class="docutils literal notranslate"><span class="pre">__get__</span></code> 的调用会被委托给底层的描述器，并会返回一个适当的 <a class="reference internal" href="#partial-objects"><span class="std std-ref">部分对象</span></a> 作为结果。</p>
<p>当 <em>func</em> 是一个非描述器类可调用对象时，则会动态创建一个适当的绑定方法。 当用作方法时其行为类似普通 Python 函数：将会插入 <em>self</em> 参数作为第一个位置参数，其位置甚至会处于提供给 <a class="reference internal" href="#functools.partialmethod" title="functools.partialmethod"><code class="xref py py-class docutils literal notranslate"><span class="pre">partialmethod</span></code></a> 构造器的 <em>args</em> 和 <em>keywords</em> 之前。</p>
<p>示例:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Cell</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="gp">... </span>        <span class="bp">self</span><span class="o">.</span><span class="n">_alive</span> <span class="o">=</span> <span class="kc">False</span>
<span class="gp">... </span>    <span class="nd">@property</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="nf">alive</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_alive</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="nf">set_state</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">state</span><span class="p">):</span>
<span class="gp">... </span>        <span class="bp">self</span><span class="o">.</span><span class="n">_alive</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
<span class="gp">... </span>    <span class="n">set_alive</span> <span class="o">=</span> <span class="n">partialmethod</span><span class="p">(</span><span class="n">set_state</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
<span class="gp">... </span>    <span class="n">set_dead</span> <span class="o">=</span> <span class="n">partialmethod</span><span class="p">(</span><span class="n">set_state</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">Cell</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">alive</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">set_alive</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">alive</span>
<span class="go">True</span>
</pre></div>
</div>
<div class="versionadded">
<p><span class="versionmodified added">3.4 新版功能.</span></p>
</div>
</dd></dl>

<dl class="function">
<dt id="functools.reduce">
<code class="sig-prename descclassname">functools.</code><code class="sig-name descname">reduce</code><span class="sig-paren">(</span><em class="sig-param">function</em>, <em class="sig-param">iterable</em><span class="optional">[</span>, <em class="sig-param">initializer</em><span class="optional">]</span><span class="sig-paren">)</span><a class="headerlink" href="#functools.reduce" title="永久链接至目标">¶</a></dt>
<dd><p>将两个参数的 <em>function</em> 从左至右累积地应用到 <em>sequence</em> 的条目，以便将该序列缩减为单一值。 例如，<code class="docutils literal notranslate"><span class="pre">reduce(lambda</span> <span class="pre">x,</span> <span class="pre">y:</span> <span class="pre">x+y,</span> <span class="pre">[1,</span> <span class="pre">2,</span> <span class="pre">3,</span> <span class="pre">4,</span> <span class="pre">5])</span></code> 是计算 <code class="docutils literal notranslate"><span class="pre">((((1+2)+3)+4)+5)</span></code> 的值。 左边的参数 <em>x</em> 是累积值而右边的参数 <em>y</em> 则是来自 <em>sequence</em> 的更新值。 如果存在可选项 <em>initializer</em>，它会被放在参与计算的序列的条目之前，并在序列对象为空时作为默认值。 如果没有给出 <em>initializer</em> 并且 <em>sequence</em> 仅包含一个条目，则将返回第一项。</p>
<p>大致相当于：</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">reduce</span><span class="p">(</span><span class="n">function</span><span class="p">,</span> <span class="n">iterable</span><span class="p">,</span> <span class="n">initializer</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="n">it</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">iterable</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">initializer</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">value</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">value</span> <span class="o">=</span> <span class="n">initializer</span>
    <span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="n">it</span><span class="p">:</span>
        <span class="n">value</span> <span class="o">=</span> <span class="n">function</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">element</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">value</span>
</pre></div>
</div>
</dd></dl>

<dl class="function">
<dt id="functools.singledispatch">
<code class="sig-prename descclassname">&#64;</code><code class="sig-prename descclassname">functools.</code><code class="sig-name descname">singledispatch</code><a class="headerlink" href="#functools.singledispatch" title="永久链接至目标">¶</a></dt>
<dd><p>将一个函数转换为 <a class="reference internal" href="../glossary.html#term-single-dispatch"><span class="xref std std-term">单分派</span></a> <a class="reference internal" href="../glossary.html#term-generic-function"><span class="xref std std-term">generic function</span></a>。</p>
<p>要定义一个泛型函数，应使用 <code class="docutils literal notranslate"><span class="pre">&#64;singledispatch</span></code> 装饰器进行装饰。 请注意分派是作用于第一个参数的类型，要相应地创建你的函数:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">singledispatch</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nd">@singledispatch</span>
<span class="gp">... </span><span class="k">def</span> <span class="nf">fun</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">if</span> <span class="n">verbose</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Let me just say,&quot;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">&quot; &quot;</span><span class="p">)</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
</pre></div>
</div>
<p>要将重载的实现添加到函数中，请使用泛型函数的 <code class="xref py py-func docutils literal notranslate"><span class="pre">register()</span></code> 属性。 它是一个装饰器。 对于带有类型标注的函数，该装饰器将自动推断第一个参数的类型:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="nd">@fun</span><span class="o">.</span><span class="n">register</span>
<span class="gp">... </span><span class="k">def</span> <span class="nf">_</span><span class="p">(</span><span class="n">arg</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">if</span> <span class="n">verbose</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Strength in numbers, eh?&quot;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">&quot; &quot;</span><span class="p">)</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nd">@fun</span><span class="o">.</span><span class="n">register</span>
<span class="gp">... </span><span class="k">def</span> <span class="nf">_</span><span class="p">(</span><span class="n">arg</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">if</span> <span class="n">verbose</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Enumerate this:&quot;</span><span class="p">)</span>
<span class="gp">... </span>    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">elem</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">elem</span><span class="p">)</span>
</pre></div>
</div>
<p>对于不使用类型标注的代码，可以将适当的类型参数显式地传给装饰器本身:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="nd">@fun</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="nb">complex</span><span class="p">)</span>
<span class="gp">... </span><span class="k">def</span> <span class="nf">_</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">if</span> <span class="n">verbose</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Better than complicated.&quot;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">&quot; &quot;</span><span class="p">)</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="n">arg</span><span class="o">.</span><span class="n">real</span><span class="p">,</span> <span class="n">arg</span><span class="o">.</span><span class="n">imag</span><span class="p">)</span>
<span class="gp">...</span>
</pre></div>
</div>
<p>要启用注册 lambda 和现有函数，可以使用函数形式的 <code class="xref py py-func docutils literal notranslate"><span class="pre">register()</span></code> 属性:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">nothing</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Nothing.&quot;</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">),</span> <span class="n">nothing</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="xref py py-func docutils literal notranslate"><span class="pre">register()</span></code> 属性将返回启用了装饰器堆栈、封存的未装饰函数，并会为每个变量单独创建单元测试:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="nd">@fun</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="nb">float</span><span class="p">)</span>
<span class="gp">... </span><span class="nd">@fun</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">Decimal</span><span class="p">)</span>
<span class="gp">... </span><span class="k">def</span> <span class="nf">fun_num</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">if</span> <span class="n">verbose</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Half of your number:&quot;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">&quot; &quot;</span><span class="p">)</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="n">arg</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun_num</span> <span class="ow">is</span> <span class="n">fun</span>
<span class="go">False</span>
</pre></div>
</div>
<p>在调用时，泛型函数会根据第一个参数的类型进行分派:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="p">(</span><span class="s2">&quot;Hello, world.&quot;</span><span class="p">)</span>
<span class="go">Hello, world.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="p">(</span><span class="s2">&quot;test.&quot;</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="go">Let me just say, test.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="p">(</span><span class="mi">42</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="go">Strength in numbers, eh? 42</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="p">([</span><span class="s1">&#39;spam&#39;</span><span class="p">,</span> <span class="s1">&#39;spam&#39;</span><span class="p">,</span> <span class="s1">&#39;eggs&#39;</span><span class="p">,</span> <span class="s1">&#39;spam&#39;</span><span class="p">],</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="go">Enumerate this:</span>
<span class="go">0 spam</span>
<span class="go">1 spam</span>
<span class="go">2 eggs</span>
<span class="go">3 spam</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
<span class="go">Nothing.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="p">(</span><span class="mf">1.23</span><span class="p">)</span>
<span class="go">0.615</span>
</pre></div>
</div>
<p>在没有用于特定类型的已注册实现的情况下，则会使用其方法解析顺序来查找更通用的实现。 以 <code class="docutils literal notranslate"><span class="pre">&#64;singledispatch</span></code> 装饰的原始函数将为最基本的 <code class="docutils literal notranslate"><span class="pre">object</span></code> 类型进行注册，这意味着它将在找不到更好的实现时被使用。</p>
<p>要检查泛型函数将为给定类型选择哪个实现，请使用 <code class="docutils literal notranslate"><span class="pre">dispatch()</span></code> 属性:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="o">.</span><span class="n">dispatch</span><span class="p">(</span><span class="nb">float</span><span class="p">)</span>
<span class="go">&lt;function fun_num at 0x1035a2840&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="o">.</span><span class="n">dispatch</span><span class="p">(</span><span class="nb">dict</span><span class="p">)</span>    <span class="c1"># note: default implementation</span>
<span class="go">&lt;function fun at 0x103fe0000&gt;</span>
</pre></div>
</div>
<p>要访问所有忆注册实现，请使用只读的 <code class="docutils literal notranslate"><span class="pre">registry</span></code> 属性:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="o">.</span><span class="n">registry</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
<span class="go">dict_keys([&lt;class &#39;NoneType&#39;&gt;, &lt;class &#39;int&#39;&gt;, &lt;class &#39;object&#39;&gt;,</span>
<span class="go">          &lt;class &#39;decimal.Decimal&#39;&gt;, &lt;class &#39;list&#39;&gt;,</span>
<span class="go">          &lt;class &#39;float&#39;&gt;])</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="o">.</span><span class="n">registry</span><span class="p">[</span><span class="nb">float</span><span class="p">]</span>
<span class="go">&lt;function fun_num at 0x1035a2840&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fun</span><span class="o">.</span><span class="n">registry</span><span class="p">[</span><span class="nb">object</span><span class="p">]</span>
<span class="go">&lt;function fun at 0x103fe0000&gt;</span>
</pre></div>
</div>
<div class="versionadded">
<p><span class="versionmodified added">3.4 新版功能.</span></p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span><code class="xref py py-func docutils literal notranslate"><span class="pre">register()</span></code> 属性支持使用类型标注。</p>
</div>
</dd></dl>

<dl class="function">
<dt id="functools.update_wrapper">
<code class="sig-prename descclassname">functools.</code><code class="sig-name descname">update_wrapper</code><span class="sig-paren">(</span><em class="sig-param">wrapper</em>, <em class="sig-param">wrapped</em>, <em class="sig-param">assigned=WRAPPER_ASSIGNMENTS</em>, <em class="sig-param">updated=WRAPPER_UPDATES</em><span class="sig-paren">)</span><a class="headerlink" href="#functools.update_wrapper" title="永久链接至目标">¶</a></dt>
<dd><p>更新一个 <em>wrapper</em> 函数以使其类似于 <em>wrapped</em> 函数。 可选参数为指明原函数的哪些属性要直接被赋值给 wrapper 函数的匹配属性的元组，并且这些 wrapper 函数的属性将使用原函数的对应属性来更新。 这些参数的默认值是模块级常量 <code class="docutils literal notranslate"><span class="pre">WRAPPER_ASSIGNMENTS</span></code> (它将被赋值给 wrapper 函数的 <code class="docutils literal notranslate"><span class="pre">__module__</span></code>, <code class="docutils literal notranslate"><span class="pre">__name__</span></code>, <code class="docutils literal notranslate"><span class="pre">__qualname__</span></code>, <code class="docutils literal notranslate"><span class="pre">__annotations__</span></code> 和 <code class="docutils literal notranslate"><span class="pre">__doc__</span></code> 即文档字符串) 以及 <code class="docutils literal notranslate"><span class="pre">WRAPPER_UPDATES</span></code> (它将更新 wrapper 函数的 <code class="docutils literal notranslate"><span class="pre">__dict__</span></code> 即实例字典)。</p>
<p>为了允许出于内省和其他目的访问原始函数（例如绕过 <a class="reference internal" href="#functools.lru_cache" title="functools.lru_cache"><code class="xref py py-func docutils literal notranslate"><span class="pre">lru_cache()</span></code></a> 之类的缓存装饰器），此函数会自动为 wrapper 添加一个指向被包装函数的 <code class="docutils literal notranslate"><span class="pre">__wrapped__</span></code> 属性。</p>
<p>此函数的主要目的是在 <a class="reference internal" href="../glossary.html#term-decorator"><span class="xref std std-term">decorator</span></a> 函数中用来包装被装饰的函数并返回包装器。 如果包装器函数未被更新，则被返回函数的元数据将反映包装器定义而不是原始函数定义，这通常没有什么用处。</p>
<p><a class="reference internal" href="#functools.update_wrapper" title="functools.update_wrapper"><code class="xref py py-func docutils literal notranslate"><span class="pre">update_wrapper()</span></code></a> 可以与函数之外的可调用对象一同使用。 在 <em>assigned</em> 或 <em>updated</em> 中命名的任何属性如果不存在于被包装对象则会被忽略（即该函数将不会尝试在包装器函数上设置它们）。 如果包装器函数自身缺少在 <em>updated</em> 中命名的任何属性则仍将引发 <a class="reference internal" href="exceptions.html#AttributeError" title="AttributeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AttributeError</span></code></a>。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.2 新版功能: </span>自动添加 <code class="docutils literal notranslate"><span class="pre">__wrapped__</span></code> 属性。</p>
</div>
<div class="versionadded">
<p><span class="versionmodified added">3.2 新版功能: </span>默认拷贝 <code class="docutils literal notranslate"><span class="pre">__annotations__</span></code> 属性。</p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.2 版更改: </span>不存在的属性将不再触发 <a class="reference internal" href="exceptions.html#AttributeError" title="AttributeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AttributeError</span></code></a>。</p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.4 版更改: </span><code class="docutils literal notranslate"><span class="pre">__wrapped__</span></code> 属性现在总是指向被包装的函数，即使该函数定义了 <code class="docutils literal notranslate"><span class="pre">__wrapped__</span></code> 属性。 (参见 <a class="reference external" href="https://bugs.python.org/issue17482">bpo-17482</a>)</p>
</div>
</dd></dl>

<dl class="function">
<dt id="functools.wraps">
<code class="sig-prename descclassname">&#64;</code><code class="sig-prename descclassname">functools.</code><code class="sig-name descname">wraps</code><span class="sig-paren">(</span><em class="sig-param">wrapped</em>, <em class="sig-param">assigned=WRAPPER_ASSIGNMENTS</em>, <em class="sig-param">updated=WRAPPER_UPDATES</em><span class="sig-paren">)</span><a class="headerlink" href="#functools.wraps" title="永久链接至目标">¶</a></dt>
<dd><p>这是一个便捷函数，用于在定义包装器函数时发起调用 <a class="reference internal" href="#functools.update_wrapper" title="functools.update_wrapper"><code class="xref py py-func docutils literal notranslate"><span class="pre">update_wrapper()</span></code></a> 作为函数装饰器。 它等价于 <code class="docutils literal notranslate"><span class="pre">partial(update_wrapper,</span> <span class="pre">wrapped=wrapped,</span> <span class="pre">assigned=assigned,</span> <span class="pre">updated=updated)</span></code>。 例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">wraps</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">my_decorator</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="gp">... </span>    <span class="nd">@wraps</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Calling decorated function&#39;</span><span class="p">)</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span>
<span class="gp">... </span>    <span class="k">return</span> <span class="n">wrapper</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nd">@my_decorator</span>
<span class="gp">... </span><span class="k">def</span> <span class="nf">example</span><span class="p">():</span>
<span class="gp">... </span>    <span class="sd">&quot;&quot;&quot;Docstring&quot;&quot;&quot;</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Called example function&#39;</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">example</span><span class="p">()</span>
<span class="go">Calling decorated function</span>
<span class="go">Called example function</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">example</span><span class="o">.</span><span class="vm">__name__</span>
<span class="go">&#39;example&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">example</span><span class="o">.</span><span class="vm">__doc__</span>
<span class="go">&#39;Docstring&#39;</span>
</pre></div>
</div>
<p>如果不使用这个装饰器工厂函数，则 example 函数的名称将变为 <code class="docutils literal notranslate"><span class="pre">'wrapper'</span></code>，并且 <code class="xref py py-func docutils literal notranslate"><span class="pre">example()</span></code> 原本的文档字符串将会丢失。</p>
</dd></dl>

<div class="section" id="partial-objects">
<span id="id1"></span><h2><a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-class docutils literal notranslate"><span class="pre">partial</span></code></a> 对象<a class="headerlink" href="#partial-objects" title="永久链接至标题">¶</a></h2>
<p><a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-class docutils literal notranslate"><span class="pre">partial</span></code></a> 对象是由 <a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-func docutils literal notranslate"><span class="pre">partial()</span></code></a> 创建的可调用对象。 它们具有三个只读属性：</p>
<dl class="attribute">
<dt id="functools.partial.func">
<code class="sig-prename descclassname">partial.</code><code class="sig-name descname">func</code><a class="headerlink" href="#functools.partial.func" title="永久链接至目标">¶</a></dt>
<dd><p>一个可调用对象或函数。 对 <a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-class docutils literal notranslate"><span class="pre">partial</span></code></a> 对象的调用将被转发给 <a class="reference internal" href="#functools.partial.func" title="functools.partial.func"><code class="xref py py-attr docutils literal notranslate"><span class="pre">func</span></code></a> 并附带新的参数和关键字。</p>
</dd></dl>

<dl class="attribute">
<dt id="functools.partial.args">
<code class="sig-prename descclassname">partial.</code><code class="sig-name descname">args</code><a class="headerlink" href="#functools.partial.args" title="永久链接至目标">¶</a></dt>
<dd><p>最左边的位置参数将放置在提供给 <a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-class docutils literal notranslate"><span class="pre">partial</span></code></a> 对象调用的位置参数之前。</p>
</dd></dl>

<dl class="attribute">
<dt id="functools.partial.keywords">
<code class="sig-prename descclassname">partial.</code><code class="sig-name descname">keywords</code><a class="headerlink" href="#functools.partial.keywords" title="永久链接至目标">¶</a></dt>
<dd><p>当调用 <a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-class docutils literal notranslate"><span class="pre">partial</span></code></a> 对象时将要提供的关键字参数。</p>
</dd></dl>

<p><a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-class docutils literal notranslate"><span class="pre">partial</span></code></a> 对象与 <code class="xref py py-class docutils literal notranslate"><span class="pre">function</span></code> 对象的类似之处在于它们都是可调用、可弱引用的对象并可拥有属性。 但两者也存在一些重要的区别。 例如前者不会自动创建 <a class="reference internal" href="stdtypes.html#definition.__name__" title="definition.__name__"><code class="xref py py-attr docutils literal notranslate"><span class="pre">__name__</span></code></a> 和 <code class="xref py py-attr docutils literal notranslate"><span class="pre">__doc__</span></code> 属性。 而且，在类中定义的 <a class="reference internal" href="#functools.partial" title="functools.partial"><code class="xref py py-class docutils literal notranslate"><span class="pre">partial</span></code></a> 对象的行为类似于静态方法，并且不会在实例属性查找期间转换为绑定方法。</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">目录</a></h3>
  <ul>
<li><a class="reference internal" href="#"><code class="xref py py-mod docutils literal notranslate"><span class="pre">functools</span></code> --- 高阶函数和可调用对象上的操作</a><ul>
<li><a class="reference internal" href="#partial-objects"><code class="xref py py-class docutils literal notranslate"><span class="pre">partial</span></code> 对象</a></li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="itertools.html"
                        title="上一章"><code class="xref py py-mod docutils literal notranslate"><span class="pre">itertools</span></code> --- 为高效循环而创建迭代器的函数</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="operator.html"
                        title="下一章"><code class="xref py py-mod docutils literal notranslate"><span class="pre">operator</span></code> --- 标准运算符替代函数</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../bugs.html">提交 Bug</a></li>
      <li>
        <a href="https://github.com/python/cpython/blob/3.7/Doc/library/functools.rst"
            rel="nofollow">显示源代码
        </a>
      </li>
    </ul>
  </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="operator.html" title="operator --- 标准运算符替代函数"
             >下一页</a> |</li>
        <li class="right" >
          <a href="itertools.html" title="itertools --- 为高效循环而创建迭代器的函数"
             >上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="functional.html" >函数式编程模块</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>  
    <div class="footer">
    &copy; <a href="../copyright.html">版权所有</a> 2001-2020, Python Software Foundation.
    <br />
    Python 软件基金会是一个非盈利组织。
    <a href="https://www.python.org/psf/donations/">请捐助。</a>
    <br />
    最后更新于 6月 29, 2020.
    <a href="../bugs.html">发现了问题</a>？
    <br />
    使用<a href="http://sphinx.pocoo.org/">Sphinx</a>2.3.1 创建。
    </div>

  </body>
</html>